using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Tao.OpenGl;
using Vj.ShapeLibrary;
using Vj.MathLibrary;
using ShapeLibrary;
using Vj.ShapeLibrary.Volumetric;
using ShapeLibrary.Volumetric;

namespace ShapeLibraryTester
{
    public partial class ShapeLibraryApp : Form
    {
        #region Private Members

        private Shape currentShape;

        private int simulationTick;
        private bool doSimulation = false;

        private float[] globalAmbient;

        private float[] light0_position;
        private float[] light1_position;
        private float[] light2_position;

        private float[] light0_ambient;
        private float[] light0_diffuse;
        private float[] light0_specular;

        private float[] light1_ambient;
        private float[] light1_diffuse;
        private float[] light1_specular;

        private float[] light2_ambient;
        private float[] light2_diffuse;
        private float[] light2_specular;

        #endregion

        #region Initialize App

        public ShapeLibraryApp()
        {
            InitializeComponent();
        }

        private void simpleOpenGlControl1_Load(object sender, EventArgs e)
        {
            simpleOpenGlControl1.InitializeContexts();
            simpleOpenGlControl1.AutoSwapBuffers = true;

            currentShape = new Cube();
            currentShape.Position = new Vector(0.0, 0.0, 0.0);
            currentShape.RotationVector = new Vector(0.0, 0.0, 0.0);
            currentShape.RotationAngle = 0.0f;
            currentShape.Scale = new Vector(1.0, 1.0, 1.0);
            currentShape.AmbientColor = Color.FromArgb(
                (int)material_ambientR_UpDown.Value,
                (int)material_ambientG_UpDown.Value,
                (int)material_diffuseB_UpDown.Value);
            currentShape.DiffuseColor = Color.FromArgb(
                (int)material_diffuseR_UpDown.Value,
                (int)material_diffuseG_UpDown.Value,
                (int)material_diffuseB_UpDown.Value);
            currentShape.SpecularColor = Color.FromArgb(
                (int)material_specularR_UpDown.Value,
                (int)material_specularG_UpDown.Value,
                (int)material_specularB_UpDown.Value);

            currentShape.Shininess = 
                (int)material_shininess_UpDown.Value;

            InitGL();
            SetLights();

            simpleOpenGlControl1_Resize(null, null);
        }

        private static bool InitGL()
        {
            //Gl.glShadeModel(Gl.GL_SMOOTH);
            Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            Gl.glClearDepth(1);
            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Gl.glDepthFunc(Gl.GL_LEQUAL);
            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
            Gl.glEnable(Gl.GL_LIGHT0);
            Gl.glEnable(Gl.GL_LIGHT1);
            Gl.glEnable(Gl.GL_LIGHT2);
            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glEnable(Gl.GL_NORMALIZE);

            return true;
        }

        private void simpleOpenGlControl1_Resize(object sender, EventArgs e)
        {
            int w = simpleOpenGlControl1.Width;
            int h = simpleOpenGlControl1.Height;

            float ratio = ((float)w / (float)h);

            // set viewport to current window size
            Gl.glViewport(0, 0, w, h);

            // set up prespective projection
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Glu.gluPerspective(45, ratio, 1, 50);

            // set up model view matrix
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
        }

        #endregion

        #region Drawing Methods

        private void simpleOpenGlControl1_Paint(object sender, PaintEventArgs e)
        {
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glLoadIdentity();

            Gl.glPushMatrix();

            Gl.glTranslatef(0.0f, 0.0f, -10.0f);

            //Gl.glRotatef(90, 1.0f, 0.0f, 0.0f);// camera angle

            SetLights();

            DrawAxis();

            PerformTests();

            currentShape.Draw();

            if (simulationTick > 10000)
            {
                simulationTimer.Stop();
                doSimulation = false;
            }

            Gl.glPopMatrix();
        }

        private void SetLights()
        {
            float globalAmbientIntensity = (float)globalAmbientUpDown.Value;
            globalAmbient =
                new float[] { globalAmbientIntensity, globalAmbientIntensity, globalAmbientIntensity, 1.0f };

            float light0_ambientIntensity = (float)light0_AmbientUpDown.Value;
            float light0_diffuseIntensity = (float)light0_DiffuseUpDown.Value;
            float light0_specularIntensity = (float)light0_SpecularUpDown.Value;

            light0_ambient =
                new float[] { light0_ambientIntensity, light0_ambientIntensity, light0_ambientIntensity, 1.0f };
            light0_diffuse =
                new float[] { light0_diffuseIntensity, light0_diffuseIntensity, light0_diffuseIntensity, 1.0f };
            light0_specular =
                new float[] { light0_specularIntensity, light0_specularIntensity, light0_specularIntensity, 1.0f };

            float light1_ambientIntensity = (float)light1_AmbientUpDown.Value;
            float light1_diffuseIntensity = (float)light1_DiffuseUpDown.Value;
            float light1_specularIntensity = (float)light1_SpecularUpDown.Value;

            light1_ambient =
                new float[] { light1_ambientIntensity, light1_ambientIntensity, light1_ambientIntensity, 1.0f };
            light1_diffuse =
                new float[] { light1_diffuseIntensity, light1_diffuseIntensity, light1_diffuseIntensity, 1.0f };
            light1_specular =
                new float[] { light1_specularIntensity, light1_specularIntensity, light1_specularIntensity, 1.0f };

            float light2_ambientIntensity = (float)light2_AmbientUpDown.Value;
            float light2_diffuseIntensity = (float)light2_DiffuseUpDown.Value;
            float light2_specularIntensity = (float)light2_SpecularUpDown.Value;

            light2_ambient =
                new float[] { light2_ambientIntensity, light2_ambientIntensity, light2_ambientIntensity, 1.0f };
            light2_diffuse =
                new float[] { light2_diffuseIntensity, light2_diffuseIntensity, light2_diffuseIntensity, 1.0f };
            light2_specular =
                new float[] { light2_specularIntensity, light2_specularIntensity, light2_specularIntensity, 1.0f };

            light0_position =
                new float[] { (float)light0_xPosUpDown.Value, 
                              (float)light0_yPosUpDown.Value, 
                              (float)light0_zPosUpDown.Value, 1.0f };

            light1_position =
                new float[] { (float)light1_xPosUpDown.Value, 
                              (float)light1_yPosUpDown.Value, 
                              (float)light1_zPosUpDown.Value, 1.0f };

            light2_position =
                new float[] { (float)light2_xPosUpDown.Value, 
                              (float)light2_yPosUpDown.Value, 
                              (float)light2_zPosUpDown.Value, 1.0f };

            Gl.glLightModelfv(Gl.GL_LIGHT_MODEL_AMBIENT, globalAmbient);

            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, light0_position);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, light0_specular);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, light0_ambient);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, light0_diffuse);

            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, light1_position);
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, light1_specular);
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, light1_ambient);
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, light1_diffuse);

            Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_POSITION, light2_position);
            Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_SPECULAR, light2_specular);
            Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_AMBIENT, light2_ambient);
            Gl.glLightfv(Gl.GL_LIGHT2, Gl.GL_DIFFUSE, light2_diffuse);


            //Sphere light0 = new Sphere();
            //light0.Position = new Vector(light0_position);
            //light0.DiffuseColor = Color.White;
            //light0.AmbientColor = Color.White;
            //light0.Scale = new Vector(0.15, 0.15, 0.15);

            //Sphere light1 = new Sphere();
            //light1.Position = new Vector(light1_position);
            //light1.DiffuseColor = Color.White;
            //light1.AmbientColor = Color.White;
            //light1.Scale = new Vector(0.15, 0.15, 0.15);

            //Sphere light2 = new Sphere();
            //light2.Position = new Vector(light2_position);
            //light2.DiffuseColor = Color.White;
            //light2.AmbientColor = Color.White;
            //light2.Scale = new Vector(0.15, 0.15, 0.15);
        }

        private void DrawAxis()
        {
            Gl.glDisable(Gl.GL_LIGHTING);

            Gl.glColor4f(0.1f, 0.1f, 0.1f, 0.1f);

            Gl.glLineWidth(0.5f);

            Gl.glBegin(Gl.GL_LINES);

            Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
            Gl.glVertex3f(1.0f, 0.0f, 0.0f);

            Gl.glEnd();


            Gl.glBegin(Gl.GL_LINES);

            Gl.glVertex3f(0.0f, -1.0f, 0.0f);
            Gl.glVertex3f(0.0f, 1.0f, 0.0f);

            Gl.glEnd();


            Gl.glBegin(Gl.GL_LINES);

            Gl.glVertex3f(0.0f, 0.0f, -1.0f);
            Gl.glVertex3f(0.0f, 0.0f, 1.0f);

            Gl.glEnd();

            Gl.glEnable(Gl.GL_LIGHTING);
        }

        #endregion

        #region Test Panel

        private void PerformTests()
        {
            if (doSimulation)
            {
                if (rotateXCheckBox.Checked)
                {
                    currentShape.RotationVector = Vector.Normalize(currentShape.RotationVector + new Vector(1.0, 0.0, 0.0));
                    currentShape.RotationAngle += 12;
                }

                if (rotateYCheckBox.Checked)
                {
                    currentShape.RotationVector = Vector.Normalize(currentShape.RotationVector + new Vector(0.0, 1.0, 0.0));
                    currentShape.RotationAngle += 12;
                }

                if (rotateZCheckBox.Checked)
                {
                    currentShape.RotationVector = Vector.Normalize(currentShape.RotationVector + new Vector(0.0, 0.0, 1.0));
                    currentShape.RotationAngle += 12;
                }

                if (translateXCheckBox.Checked)
                {
                    currentShape.Position.X = 3.0 * Math.Sin(simulationTick * Math.PI / 180.0);
                }

                if (translateYCheckBox.Checked)
                {
                    currentShape.Position.Y = 3.0 * Math.Sin(simulationTick * Math.PI / 180.0);
                }

                if (translateZCheckBox.Checked)
                {
                    currentShape.Position.Z = 3.0 * Math.Sin(simulationTick * Math.PI / 180.0);
                }

                if (scaleCheckBox.Checked)
                {
                    double scaleFactor = 1.0;
                    currentShape.Scale.X = scaleFactor * Math.Abs(Math.Sin(simulationTick * Math.PI / 180.0)) + 0.1;
                    currentShape.Scale.Y = scaleFactor * Math.Abs(Math.Sin(simulationTick * Math.PI / 180.0)) + 0.1;
                    currentShape.Scale.Z = scaleFactor * Math.Abs(Math.Sin(simulationTick * Math.PI / 180.0)) + 0.1;
                }

                if (cameraCheckBox.Checked)
                { 
                
                
                }
            }
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            simulationTick = 0;

            doSimulation = true;
            simulationTimer.Start();
        }

        private void simulationTimer_Tick(object sender, EventArgs e)
        {
            simulationTick++;
            simpleOpenGlControl1.Refresh();
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            simulationTimer.Stop();
            doSimulation = false;
        }

        private void resetButton_Click(object sender, EventArgs e)
        {
            ResetShape();
        }

        #endregion

        private void ResetShape()
        { 
            currentShape.Position = new Vector(0.0, 0.0, 0.0);
            currentShape.RotationVector = new Vector(0.0, 0.0, 0.0);
            currentShape.RotationAngle = 0.0f;
            currentShape.Scale = new Vector(1.0, 1.0, 1.0);
            currentShape.AmbientColor = Color.FromArgb(
                (int)material_ambientR_UpDown.Value,
                (int)material_ambientG_UpDown.Value,
                (int)material_diffuseB_UpDown.Value);
            currentShape.DiffuseColor = Color.FromArgb(
                (int)material_diffuseR_UpDown.Value,
                (int)material_diffuseG_UpDown.Value,
                (int)material_diffuseB_UpDown.Value);
            currentShape.SpecularColor = Color.FromArgb(
                (int)material_specularR_UpDown.Value,
                (int)material_specularG_UpDown.Value,
                (int)material_specularB_UpDown.Value);

            currentShape.Shininess = (int)material_shininess_UpDown.Value;
        }

        #region Shapes Panel

        private void sphereRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (sphereRadioButton.Checked)
                currentShape = new Sphere();

            ResetShape();
            simpleOpenGlControl1.Refresh();
        }

        private void cuboidRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (cubeRadioButton.Checked)
                currentShape = new Cube();

            ResetShape();
            simpleOpenGlControl1.Refresh();
        }

        private void cylinderRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (cylinderRadioButton.Checked)
                currentShape = new Cylinder();

            ResetShape();
            simpleOpenGlControl1.Refresh();
        }

        private void coneRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (coneRadioButton.Checked)
                currentShape = new Cone();

            ResetShape();
            simpleOpenGlControl1.Refresh();
        }

        private void testCubeRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            //if (testCubeRadioButton.Checked)
            //currentShape = new 

            //ResetShape();
            //simpleOpenGlControl1.Refresh();
        }

        #endregion

        #region Material Panel

        private void ambientColorChooserButton_Click(object sender, EventArgs e)
        {
            ambientColorDialog.AllowFullOpen = true;
            ambientColorDialog.FullOpen = true;
            ambientColorDialog.ShowHelp = true;
            ambientColorDialog.Color = Color.Black;
            ambientColorDialog.ShowDialog();
            material_ambientR_UpDown.Value = ambientColorDialog.Color.R;
            material_ambientG_UpDown.Value = ambientColorDialog.Color.G;
            material_ambientB_UpDown.Value = ambientColorDialog.Color.B;

            currentShape.AmbientColor = ambientColorDialog.Color;

            simpleOpenGlControl1.Refresh();
        }

        private void diffuseColorChooserButton_Click(object sender, EventArgs e)
        {
            diffuseColorDialog.AllowFullOpen = true;
            diffuseColorDialog.FullOpen = true;
            diffuseColorDialog.ShowHelp = true;
            diffuseColorDialog.Color = Color.Black;
            diffuseColorDialog.ShowDialog();
            material_diffuseR_UpDown.Value = diffuseColorDialog.Color.R;
            material_diffuseG_UpDown.Value = diffuseColorDialog.Color.G;
            material_diffuseB_UpDown.Value = diffuseColorDialog.Color.B;

            currentShape.DiffuseColor = diffuseColorDialog.Color;
            simpleOpenGlControl1.Refresh();
        }

        private void specularColorChooserButton_Click(object sender, EventArgs e)
        {
            specularColorDialog.AllowFullOpen = true;
            specularColorDialog.FullOpen = true;
            specularColorDialog.ShowHelp = true;
            specularColorDialog.Color = Color.Black;
            specularColorDialog.ShowDialog();
            material_specularR_UpDown.Value = specularColorDialog.Color.R;
            material_specularG_UpDown.Value = specularColorDialog.Color.G;
            material_specularB_UpDown.Value = specularColorDialog.Color.B;

            currentShape.SpecularColor = specularColorDialog.Color;
            simpleOpenGlControl1.Refresh();
        }




        #endregion

        #region Lights Panel

        private void globalAmbientUpDown_ValueChanged(object sender, EventArgs e)
        {
            globalAmbient[0] = (float)globalAmbientUpDown.Value;
            globalAmbient[1] = (float)globalAmbientUpDown.Value;
            globalAmbient[2] = (float)globalAmbientUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0_AmbientUpDown_ValueChanged(object sender, EventArgs e)
        {
            light0_ambient[0] = (float)light0_AmbientUpDown.Value;
            light0_ambient[1] = (float)light0_AmbientUpDown.Value;
            light0_ambient[2] = (float)light0_AmbientUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0_DiffuseUpDown_ValueChanged(object sender, EventArgs e)
        {
            light0_diffuse[0] = (float)light0_DiffuseUpDown.Value;
            light0_diffuse[1] = (float)light0_DiffuseUpDown.Value;
            light0_diffuse[2] = (float)light0_DiffuseUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0_SpecularUpDown_ValueChanged(object sender, EventArgs e)
        {
            light0_specular[0] = (float)light0_SpecularUpDown.Value;
            light0_specular[1] = (float)light0_SpecularUpDown.Value;
            light0_specular[2] = (float)light0_SpecularUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light1_AmbientUpDown_ValueChanged(object sender, EventArgs e)
        {
            light1_ambient[0] = (float)light1_AmbientUpDown.Value;
            light1_ambient[1] = (float)light1_AmbientUpDown.Value;
            light1_ambient[2] = (float)light1_AmbientUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light1_DiffuseUpDown_ValueChanged(object sender, EventArgs e)
        {
            light1_diffuse[0] = (float)light1_DiffuseUpDown.Value;
            light1_diffuse[1] = (float)light1_DiffuseUpDown.Value;
            light1_diffuse[2] = (float)light1_DiffuseUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light1_SpecularUpDown_ValueChanged(object sender, EventArgs e)
        {
            light1_specular[0] = (float)light1_SpecularUpDown.Value;
            light1_specular[1] = (float)light1_SpecularUpDown.Value;
            light1_specular[2] = (float)light1_SpecularUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light2_AmbientUpDown_ValueChanged(object sender, EventArgs e)
        {
            light2_ambient[0] = (float)light2_AmbientUpDown.Value;
            light2_ambient[1] = (float)light2_AmbientUpDown.Value;
            light2_ambient[2] = (float)light2_AmbientUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light2_DiffuseUpDown_ValueChanged(object sender, EventArgs e)
        {
            light2_diffuse[0] = (float)light2_DiffuseUpDown.Value;
            light2_diffuse[1] = (float)light2_DiffuseUpDown.Value;
            light2_diffuse[2] = (float)light2_DiffuseUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light2_SpecularUpDown_ValueChanged(object sender, EventArgs e)
        {
            light2_specular[0] = (float)light2_SpecularUpDown.Value;
            light2_specular[1] = (float)light2_SpecularUpDown.Value;
            light2_specular[2] = (float)light2_SpecularUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0_xPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light0_position[0] = (float)light0_xPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0_yPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light0_position[1] = (float)light0_yPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0_zPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light0_position[2] = (float)light0_zPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light1_xPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light1_position[0] = (float)light1_xPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light1_yPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light1_position[1] = (float)light1_yPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light1_zPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light1_position[2] = (float)light1_zPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light2_xPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light2_position[0] = (float)light2_xPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light2_yPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light2_position[1] = (float)light2_yPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light2_zPosUpDown_ValueChanged(object sender, EventArgs e)
        {
            light2_position[2] = (float)light2_zPosUpDown.Value;

            simpleOpenGlControl1.Refresh();
        }

        private void light0CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (!light0CheckBox.Checked)
            {
                light0_AmbientUpDown.Value = 0.0M;
                light0_DiffuseUpDown.Value = 0.0M;
                light0_SpecularUpDown.Value = 0.0M;
            }
            else
            {
                light0_AmbientUpDown.Value = 0.5M;
                light0_DiffuseUpDown.Value = 0.5M;
                light0_SpecularUpDown.Value = 0.5M;
            }

            simpleOpenGlControl1.Refresh();
        }

        private void light1CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (!light1CheckBox.Checked)
            {
                light1_AmbientUpDown.Value = 0.0M;
                light1_DiffuseUpDown.Value = 0.0M;
                light1_SpecularUpDown.Value = 0.0M;
            }
            else
            {
                light1_AmbientUpDown.Value = 0.5M;
                light1_DiffuseUpDown.Value = 0.5M;
                light1_SpecularUpDown.Value = 0.5M;
            }

            simpleOpenGlControl1.Refresh();
        }

        private void light2CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (!light2CheckBox.Checked)
            {
                light2_AmbientUpDown.Value = 0.0M;
                light2_DiffuseUpDown.Value = 0.0M;
                light2_SpecularUpDown.Value = 0.0M;
            }
            else
            {
                light2_AmbientUpDown.Value = 0.5M;
                light2_DiffuseUpDown.Value = 0.5M;
                light2_SpecularUpDown.Value = 0.5M;
            }

            simpleOpenGlControl1.Refresh();
        }

        private void globalLightCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (!globalLightCheckBox.Checked)
            {
                globalAmbientUpDown.Value = 0.0M;
            }
            else
            {
                globalAmbientUpDown.Value = 0.5M;
            }

        }

        #endregion

        #region Options Panel

        private void smoothShadingCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (smoothShadingCheckBox.Checked)
                Gl.glShadeModel(Gl.GL_SMOOTH);
            else
                Gl.glShadeModel(Gl.GL_FLAT);

            simpleOpenGlControl1.Refresh();
        }

        private void actionCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            // keep at bottom
            if (actionCheckBox.Checked)
            {
                rotateXCheckBox.Checked = RandomGrabber.NextBoolean();
                rotateYCheckBox.Checked = RandomGrabber.NextBoolean();
                rotateZCheckBox.Checked = RandomGrabber.NextBoolean();
                translateXCheckBox.Checked = RandomGrabber.NextBoolean();
                translateYCheckBox.Checked = RandomGrabber.NextBoolean();
                translateZCheckBox.Checked = RandomGrabber.NextBoolean();
                scaleCheckBox.Checked = RandomGrabber.NextBoolean();

            }

        }

        private void speedScrollBar_Scroll(object sender, ScrollEventArgs e)
        {
            simulationTimer.Interval = speedScrollBar.Value;
        }

        #endregion


    }
}